using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace BridgeUI
{
    public class World
    {
        internal World(BrApp app)
        {
            App = app;
            controls = new ControlCollection(this);
            Observer = new Observer(this);
            BackGround = Color.GreenYellow;
        }

        public BrApp App { get; private set; }

        internal void Init()
        {
            Observer.Init();
        }

        #region Controls
        private ControlCollection controls;
        class ControlCollection : List<Control>, ICollection<Control>
        {
            public ControlCollection(World world)
            {
                Owner = world;
            } 
            public World Owner;
            public new void Add(Control item)
            {
                item.World = Owner;
                item.OnLoading();
                base.Add(item);
                item.OnLoaded();
            }

            public new bool Remove(Control item)
            {
                if (item.World != Owner) return false;
                item.OnUnLoading();
                base.Remove(item);
                item.OnUnLoaded();
                item.World = null;
                return true;
            }
        }
        public ICollection<Control> Controls { get { return controls; } }
        private Control _focused;
        // not implenment! xee
        public Control Focused
        {
            get { return _focused; }
            private set
            {
                if (_focused == value) return;
                if (_focused != null) _focused.OnFocusLeave();
                _focused = value;
                if (_focused != null) _focused.OnFocusEnter();
            }
        }
        private Control _underFocusRay;

        public Control UnderFocusRay
        {
            get { return _underFocusRay; }
            set
            {
                if (value == _underFocusRay) return;
                if (value != null) value.OnFocusRayLeave();
                _underFocusRay = value;
                if (value != null) value.OnFocusRayHover();
            }
        }
        /// <summary>
        /// warning :not implented! xee
        /// </summary>
        public Control Visioned;
        Control findUnderFocuseControl()
        {
            float? re = null;
            Control mi = null;
            foreach (var con in controls)
            {
                var now = con.ClickTest(Observer.FocusRay);
                if (re < now || (!re.HasValue && now.HasValue)) // if (re == null || now == null) (re < now) is false
                {
                    re = now;
                    mi = con;
                } 
            }
            return mi;
        }

        public void Focus(Control control)
        {
            Focused = control;
        }

        void ControlsUpdate(GameTime gameTime)
        {
            UnderFocusRay = findUnderFocuseControl();

            foreach (var con in Controls)
                con.Update(gameTime);
        }
        #endregion

        public Observer Observer { get; private set; }

        public Color BackGround { get; set; }

        internal void Draw(GameTime gameTime)
        {
            foreach (var con in Controls)
                con.Draw(gameTime);
        }

        internal void Update(GameTime gameTime)
        {
            Observer.Update(gameTime);
            ControlsUpdate(gameTime);
        }
    }
}
